using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using OWED.Network.Messages;
using OWED.Network.Messages.General;
using OWED.Network.Messages.Reply;
using OWED.Network;

using System.Xml;

using ClientGUI.Widgets;
namespace ClientGUI.Main.PopUpWindows
{
    /// <summary>
    /// This form exists to give an interface to retrieve a 
    /// document from the backend.
    /// </summary>
    public partial class GetDocument : NetworkDialog
    {
        /// <summary>
        /// A delegate for Invoke
        /// </summary>
        public delegate void DocumentSetter(XmlDocument doc);
        /// <summary>
        /// A delegate for Invoke
        /// </summary>
        public delegate void DocNameSetter(DocName name);

        /// <summary>
        /// This function exists to aid Invoke.
        /// </summary>
        private void DocNameSet(DocName name)
        {
            my_parent.ProgramData.DocName = name;
        }

        /// <summary>
        /// The window that created this one
        /// </summary>
        MainForm my_parent;
        /// <summary>
        /// Get the document from the form
        /// </summary>
        /// <param name="main"></param>
        public GetDocument(MainForm main):base("Get Document:", main)
        {
            InitializeComponent();
            my_parent = main;

            version_view.Enabled = false;

            Refresh();
            Show();

            list_documents();
        }


        /// <summary>
        /// Polls the server for the documents and displays them.
        /// </summary>
        private void list_documents()
        {
            StatusMessage("Getting Document List");
            GetDocumentList gl = new GetDocumentList(my_parent.ProgramData.User);


            try
            {
                XmlDocument r = my_parent.ProgramData.Connection.Send(gl.ToXml());
                if (r != null)
                {
                    IProtocolItem reply = MessageGet.GetFromXml(r
                        );
                    if ((reply as PassFail) != null)
                    {
                        PassFail f = reply as PassFail;
                        StatusMessage(f.Reason.Value);
                    }
                    else
                    {
                        DocumentListReply list = reply as DocumentListReply;
                        for (int i = 0; i < list.DocumentNames.Count; ++i)
                        {
                            doc_lst.Items.Add(list.DocumentNames[i].name);
                        }
                    }
                }
                else
                {
                    StatusMessage("");
                    Dispose(); //everything else gets handled automatically.
                }
            }
            catch (ConnectionException exc)
            {
                my_parent.Error(exc.Message);
                my_parent.Connected = false;
                Dispose();
            }
            StatusMessage("Choose a Document");
        }


        /// <summary>
        /// Gets and sets a document to be displayed given a name
        /// </summary>
        /// <param name="name"></param>
        private void DocumentGetter(String name)
        {
            StatusMessage("Getting document: " + name);
            OWED.Network.Messages.GetDocument request =
                new OWED.Network.Messages.GetDocument(my_parent.ProgramData.User,
                                                    new DocName(name));

            OWEDReply call = delegate(XmlDocument re)
            {
                IProtocolItem r = MessageGet.GetFromXml(re);

                if ((r as DocumentReply) != null)
                {
                    Invoke(new DocumentSetter(my_parent.SetDocument), 
                        (r as DocumentReply).ADocument.GetDocument());
                    Invoke(new StringMethodCall(StatusMessage), "Got Document: " + name);
                    Invoke(new DocNameSetter(DocNameSet), new DocName(name));
                    Invoke(new MethodInvoker(Dispose));
                }
                else
                {
                    MethodInvoker setdocname = delegate()
                    {
                        my_parent.ProgramData.DocName = new DocName(name);
                    };

                    PassFail reply = r as PassFail;
                    Invoke(new StringMethodCall(StatusMessage), reply.Reason.Value);
                    Invoke(new MethodInvoker(Dispose));
                }
            };
            
            try
            {
                my_parent.ProgramData.Connection.Send(request.ToXml(), call);
            }
            catch (ConnectionException exc)
            {
                my_parent.Error(exc.Message);
            }
        }

        

        private void button1_Click(object sender, EventArgs e)
        {
            DocumentGetter(doc_lst.SelectedItems[0].Text);
        }

        private void doc_lst_SelectedIndexChanged(object sender, EventArgs e)
        {
            //Fill in document version stuffs..
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Dispose();
        }
    }
}